<template>
  <div class="tui-table-wrapper" :class="{ 'tui-table-wrapper--has-fixed-header': hasFixedHeader }" :style="wrapperStyle">
    <!-- 隐藏的容器用于渲染子组件（TableColumn）但不直接显示在DOM中 -->
    <div style="display: none;">
      <slot></slot>
    </div>

    <!-- 使用自定义滚动条组件包裹表格 -->
    <tui-scrollbar 
      :style="scrollbarStyle"
      :show-only-when-needed="true"
      :show-horizontal="true"
      :show-vertical="true">
      <!-- 添加一个包装层，确保内容能够正确触发滚动 -->
      <div style="width: 100%;">
        <table :class="[
          'tui-table',
          {
            'tui-table--border': props.border,
            'tui-table--stripe': props.stripe,
            'tui-table--small': props.size === 'small',
            'tui-table--mini': props.size === 'mini',
            'tui-table--medium': props.size === 'medium'
          }
        ]" :style="tableStyle" cellspacing="0" cellpadding="0" border="0">
      <!-- 表头 -->
      <thead v-if="props.showHeader" class="tui-table__header">
        <template v-for="(headerRow, rowIndex) in flattenColumns" :key="`header-row-${rowIndex}`">
          <tr>
            <th v-for="(column, index) in headerRow" :key="index" :class="[
              'tui-table__header-cell',
              column.className,
              column.labelClassName,
              {
                [`tui-table__cell--${column.fixed}`]: column.fixed,
                [`is-${column.type}`]: column.type,
                'tui-table__cell--with-selection': selectionColumnVisible,
                'tui-table__cell--with-expand': expandColumnVisible,
                'tui-table__cell--with-index': indexColumnVisible,
                'tui-table__cell--hidden': column.isHidden
              }
            ]" :style="getColumnStyle(column)" :rowspan="column.rowspan || 1" :colspan="column.colspan || 1">
              <div class="tui-table__cell-wrapper">
                <template v-if="column.type === 'selection'">
                  <input type="checkbox" class="tui-checkbox__original" :checked="isAllSelected"
                    @change="toggleAllSelection" />
                  <span class="tui-checkbox__inner"></span>
                </template>
                <template v-else-if="column.type === 'index'">
                  <span class="tui-table__index">
                    {{ rowIndex + 1 }}
                  </span>
                </template>
                <template v-else>
                  <span class="tui-table__column-label">{{ column.label }}</span>
                  <span v-if="column.sortable" class="tui-table__sortable" @click="handleSortByColumn(column)">
                    <tui-icon icon="tui:up" :class="{
                      'is-active': sortState && sortState.prop === column.prop && sortState.order === 'asc'
                    }"></tui-icon>
                    <tui-icon icon="tui:down" :class="{
                      'is-active': sortState && sortState.prop === column.prop && sortState.order === 'desc'
                    }"></tui-icon>
                  </span>
                </template>
              </div>
            </th>
          </tr>
        </template>
      </thead>

      <!-- 表格内容 -->
      <tbody class="tui-table__body">
        <tr v-for="(row, rowIndex) in data" :key="rowIndex" :class="[
          'tui-table__row',
          getRowClassName(row, rowIndex),
          {
            'tui-table__row--hover': rowIndex === hoveredRowIndex,
            'tui-table__row--current': rowIndex === currentRowIndex
          }
        ]" @mouseenter="hoveredRowIndex = rowIndex" @mouseleave="hoveredRowIndex = null">
          <td v-for="(column, colIndex) in leafColumns" :key="colIndex" :class="[
            'tui-table__cell',
            column.className,
            {
              [`tui-table__cell--${column.fixed}`]: column.fixed,
              [`is-${column.type}`]: column.type,
              'tui-table__cell--with-selection': selectionColumnVisible,
              'tui-table__cell--with-expand': expandColumnVisible,
              'tui-table__cell--with-index': indexColumnVisible,
              'tui-table__cell--overflow-tooltip': column.showOverflowTooltip
            }
          ]" :style="getColumnStyle(column)">
            <div class="tui-table__cell-wrapper">
              <template v-if="column.type === 'selection'">
                <input type="checkbox" class="tui-checkbox__original" :checked="isSelected(row)"
                  @change="() => toggleRowSelection(row)" />
                <span class="tui-checkbox__inner"></span>
              </template>
              <template v-else-if="column.type === 'index'">
                <span class="tui-table__index">
                  {{ rowIndex + 1 }}
                </span>
              </template>
              <template v-else>
                <slot v-if="column.slotName" :name="column.slotName" :row="row" :column="column" :index="rowIndex">
                </slot>
                <template v-else-if="column.formatter">
                  {{ column.formatter(row, column) }}
                </template>
                <span v-else-if="column.prop">
                  <div v-if="column.showOverflowTooltip" class="tui-table__overflow-tooltip-wrapper"
                    :title="objects.getProp(row, column.prop)">
                    {{ objects.getProp(row, column.prop) }}
                  </div>
                  <span v-else>
                    {{ objects.getProp(row, column.prop) }}
                  </span>
                </span>
              </template>
            </div>
          </td>
        </tr>

        <!-- 空数据状态 -->
        <tr v-if="data.length === 0" class="tui-table__empty-row">
          <td :colspan="leafColumns.length || 1" class="tui-table__empty-cell">
            <span class="tui-table__empty-text">{{ props.emptyText }}</span>
          </td>
        </tr>
      </tbody>

      <!-- 表尾 -->
      <tfoot v-if="props.showFooter" class="tui-table__footer">
        <!-- 表尾内容可以在这里自定义 -->
      </tfoot>
    </table>
      </div>
    </tui-scrollbar>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, watch, provide, nextTick } from 'vue';
import { TuiIcon } from '../icon';
import type { TableProps, TableColumnProps, TableSortState, TableContext } from './types';
import { tree, objects, arrays, strings } from '../../../index';
import {
  toggleRowSelection as toggleRowSelectionHelper
} from './helpers';

// Props
const props = withDefaults(defineProps<TableProps>(), {
  // 表格数据默认为空数组
  data: () => [],
  // 默认不显示斑马纹
  stripe: false,
  // 默认不显示边框
  border: false,
  // 默认不设置固定高度
  height: undefined,
  // 默认不设置最大高度
  maxHeight: undefined,
  // 默认不设置行类名
  rowClassName: '',
  // 默认不设置行键
  rowKey: '',
  // 默认显示表头
  showHeader: true,
  // 默认不显示表尾
  showFooter: false,
  // 默认不高亮当前行
  highlightCurrentRow: false,
  // 默认不设置当前行键
  currentRowKey: undefined,
  // 默认表格尺寸为default
  size: 'default',
  // 默认空表格文本
  emptyText: '暂无数据',
  // 在列没有设置宽度时，默认表格布局为auto，设置时为fixed
  tableLayout: undefined
});

// Emits
const emit = defineEmits<{
  'update:data': [data: Record<string, any>[]];
  'sort-change': [sortState: TableSortState];
  'selection-change': [selection: Record<string, any>[]];
  'current-change': [currentRow: Record<string, any> | null, oldCurrentRow: Record<string, any> | null];
}>();

// 内部数据
const internalData = ref<Record<string, any>[]>(props.data || []);
const columns = ref<TableColumnProps[]>([]);
const sortState = ref<TableSortState | null>(null);

const selectedRows = ref<Record<string, any>[]>([]);
const currentRow = ref<Record<string, any> | null>(null);
const currentRowIndex = ref<number | null>(null);
const oldCurrentRow = ref<Record<string, any> | null>(null);
const hasFixedHeader = ref(false);
const hoveredRowIndex = ref<number | null>(null);

/**
 * 计算表格容器样式属性
 * 
 * @returns {Record<string, any>} - 表格容器样式对象
 */
const wrapperStyle = computed(() => {
  const style: Record<string, any> = {};
  
  // 设置基础样式
  style.position = 'relative';
  style.overflow = 'hidden';
  
  return style;
});

/**
 * 计算滚动条组件样式属性
 * 将高度属性应用到滚动条组件上
 * 
 * @returns {Record<string, any>} - 滚动条组件样式对象
 */
const scrollbarStyle = computed(() => {
  const style: Record<string, any> = {};
  
  // 处理高度属性，确保有单位
  if (props.height) {
    style.height = strings.ensureUnit(props.height, 'px');
  }
  if (props.maxHeight) {
    style.maxHeight = strings.ensureUnit(props.maxHeight, 'px');
  }
  
  return style;
});

/**
 * 计算表格样式属性
 * 
 * @returns {Record<string, any>} - 包含tableLayout属性的样式对象
 */
const tableStyle = computed(() => {
  const style: Record<string, any> = {};
  
  // 添加tableLayout属性
  if (props.tableLayout) {
    style.tableLayout = props.tableLayout;
  } else {
    // 检查是否有列设置了宽度相关的属性
    const hasColumnWithWidth = leafColumns.value.some(column => 
      column.width !== undefined || 
      column.minWidth !== undefined || 
      column.maxWidth !== undefined || 
      column.flex !== undefined
    );
    
    // 如果有列设置了宽度属性，则tableLayout强制设置为fixed，否则为auto
    style.tableLayout = hasColumnWithWidth ? 'fixed' : 'auto';
  }
  
  return style;
});

/**
 * 获取表格数据
 * 
 * @returns {Record<string, any>[]} - 表格数据数组
 * 
 * @example
 * const tableData = data.value;
 * // 使用表格数据进行渲染或操作
 */
const data = computed(() => {
  return internalData.value;
});

/**
 * 计算多级表头的扁平化结构
 * 将树形结构的列定义转换为适用于表格渲染的二维数组
 * 
 * @returns {TableColumnProps[][]} - 多级表头的二维数组结构，每层对应一个数组
 * 
 * @example
 * // 假设有如下列定义
 * const columns = [
 *   { label: '姓名', prop: 'name' },
 *   { 
 *     label: '联系方式', 
 *     children: [
 *       { label: '电话', prop: 'phone' },
 *       { label: '邮箱', prop: 'email' }
 *     ]
 *   }
 * ];
 * // flattenColumns.value 结果:
 * // [
 * //   [{ label: '姓名', ... }, { label: '联系方式', colspan: 2, ... }],
 * //   [{ label: '电话', ... }, { label: '邮箱', ... }]
 * // ]
 */
const flattenColumns = computed(() => {
  // 计算多级表头的结构
  const headers: TableColumnProps[][] = [];
  const maxLevel = tree.depth(columns.value);

  for (let level = 0; level < maxLevel; level++) {
    headers[level] = [];
  }

  processColumns(columns.value, headers, 0, 0);
  return headers;
});

/**
 * 获取所有叶子节点列
 * 叶子节点列是没有子列的列，通常用于表格内容的渲染
 * 
 * @returns {TableColumnProps[]} - 叶子节点列数组
 * 
 * @example
 * // 对于包含多级表头的列定义
 * const leafs = leafColumns.value;
 * // leafs 结果: 仅包含最底层的叶子节点列
 */
const leafColumns = computed(() => {
  return tree.leafs(columns.value);
});

/**
 * 处理树形结构的表格列定义，将多层级表头转换为二维数组结构
 * 
 * @param {TableColumnProps[]} cols - 列定义数组，可能包含子列
 * @param {TableColumnProps[][]} headers - 用于存储处理结果的二维数组，每个层级对应一个数组
 * @param {number} currentLevel - 当前处理的层级索引，从0开始
 * @param {number} startIndex - 当前层级的起始列索引
 * 
 * @example
 * // 处理简单的多层级表头
 * const columns = [
 *   { prop: 'name', label: '姓名' },
 *   { 
 *     label: '联系方式', 
 *     children: [
 *       { prop: 'phone', label: '电话' },
 *       { prop: 'email', label: '邮箱' }
 *     ]
 *   }
 * ];
 * const headers = [[], []]; // 假设已知最大深度为2
 * processColumns(columns, headers, 0, 0);
 * // headers 结果:
 * // [
 * //   [{ label: '姓名' }, { label: '联系方式', colspan: 2 }],
 * //   [{ prop: 'phone', label: '电话' }, { prop: 'email', label: '邮箱' }]
 * // ]
 */
function processColumns(
  cols: TableColumnProps[],
  headers: TableColumnProps[][],
  currentLevel: number,
  startIndex: number
): void {
  cols.forEach(col => {
    if (col.children && col.children.length > 0) {
      const colspan = tree.countLeaves(col.children);
      const rowspan = headers.length - currentLevel;

      headers[currentLevel][startIndex] = {
        ...col,
        colspan,
        rowspan
      };

      processColumns(col.children, headers, currentLevel + 1, startIndex);
      startIndex += colspan;
    } else {
      headers[currentLevel][startIndex] = col;
      startIndex++;
    }
  });
}

// 计算叶子节点数量
/**
 * 检查是否需要固定表头
 * 当设置了height或maxHeight属性时，将表格设置为固定表头模式
 *
 * @example
 * // 当height属性改变时会自动调用
 * checkFixedHeader();
 */
function checkFixedHeader() {
  nextTick(() => {
    hasFixedHeader.value = !!(props.height || props.maxHeight);
  });
}

/**
 * 检查是否所有行都被选中
 * 
 * @returns {boolean} - 如果所有行都被选中则返回true，否则返回false
 * 
 * @example
 * if (isAllSelected.value) {
 *   // 执行全选状态下的操作
 * }
 */
const isAllSelected = computed(() => {
  return data.value.length > 0 && selectedRows.value.length === data.value.length;
});

/**
 * 检查表格是否包含选择列
 * 
 * @returns {boolean} - 如果包含选择列则返回true，否则返回false
 * 
 * @example
 * if (selectionColumnVisible.value) {
 *   // 显示选择相关的功能
 * }
 */
const selectionColumnVisible = computed(() => {
  return columns.value.some(column => column.type === 'selection');
});

/**
 * 检查表格是否包含展开列
 * 
 * @returns {boolean} - 如果包含展开列则返回true，否则返回false
 * 
 * @example
 * if (expandColumnVisible.value) {
 *   // 处理行展开相关的逻辑
 * }
 */
const expandColumnVisible = computed(() => {
  return columns.value.some(column => column.type === 'expand');
});

/**
 * 检查表格是否包含索引列
 * 
 * @returns {boolean} - 如果包含索引列则返回true，否则返回false
 * 
 * @example
 * if (indexColumnVisible.value) {
 *   // 显示行索引
 * }
 */
const indexColumnVisible = computed(() => {
  return columns.value.some(column => column.type === 'index');
});

/**
 * 获取表格列的样式属性
 * 从列定义中提取与宽度相关的样式属性
 *
 * @param {TableColumnProps} column - 列定义对象
 * @returns {Object} - 包含width、minWidth、maxWidth、flex属性的样式对象
 *
 * @example
 * const columnStyle = getColumnStyle(column);
 * // columnStyle 结果: { width: '100px', minWidth: '80px', ... }
 */
function getColumnStyle(column: TableColumnProps) {
  const style: Record<string, any> = {};
  
  // 处理宽度属性，确保有单位
  if (column.width) {
    style.width = strings.ensureUnit(column.width, 'px');
  }
  if (column.minWidth) {
    style.minWidth = strings.ensureUnit(column.minWidth, 'px');
  }
  if (column.maxWidth) {
    style.maxWidth = strings.ensureUnit(column.maxWidth, 'px');
  }
  
  // 添加flex属性
  if (column.flex) {
    style.flex = column.flex;
  }
  
  return style;
}

/**
 * 获取表格行的类名
 * 根据行数据、索引和rowClassName配置获取行的类名
 *
 * @param {Record<string, any>} row - 行数据对象
 * @param {number} index - 行索引
 * @returns {string | undefined} - 行的类名字符串或undefined
 *
 * @example
 * const rowClassName = getRowClassName(row, index);
 * // 可能返回: 'custom-row-class' 或 undefined
 */
function getRowClassName(row: Record<string, any>, index: number) {
  if (typeof props.rowClassName === 'function') {
    return props.rowClassName(row, index);
  }
  return props.rowClassName || '';
}



/**
 * 处理表格列的排序逻辑
 * @param {TableColumnProps} column - 要排序的列配置
 * @example
 * // 当用户点击可排序列的表头时调用
 * handleSortByColumn(column);
 */
function handleSortByColumn(column: TableColumnProps) {
  // 检查列是否可排序
  if (!column.prop || !column.sortable) {
    return;
  }

  // 确定新的排序顺序
  let order: 'asc' | 'desc' | null = null;
  if (sortState.value && sortState.value.prop === column.prop) {
    // 如果点击的是当前排序的列，则切换排序顺序
    if (sortState.value.order === 'asc') {
      order = 'desc';
    } else if (sortState.value.order === 'desc') {
      order = null;
    }
  } else {
    // 如果点击的是新的列，则默认升序排列
    order = 'asc';
  }

  // 更新排序状态
  sortState.value = order ? { prop: column.prop, order } : null;

  // 执行数据排序
  if (sortState.value && order) {
    // 触发排序变化事件
    emit('sort-change', sortState.value);

    // 创建数据副本以避免修改原数组
    internalData.value = [...internalData.value].sort((a, b) => {
      if (column.sortMethod) {
        // 使用自定义排序方法对完整的行对象进行排序
        const compareResult = column.sortMethod(a, b);
        // 根据排序顺序调整比较结果
        return order === 'asc' ? compareResult : -compareResult;
      } else {
        // 使用从arrays模块导入的defaultSort函数进行默认排序
        const prop = sortState.value!.prop;
        const valueA = a[prop];
        const valueB = b[prop];
        return arrays.defaultSort(valueA, valueB, order);
      }
    });
  }
}

/**
 * 检查指定行是否被选中
 * 根据行数据和rowKey配置判断行是否在已选行集合中
 *
 * @param {Record<string, any>} row - 要检查的行数据对象
 * @returns {boolean} - 如果行被选中则返回true，否则返回false
 *
 * @example
 * if (isSelected(row)) {
 *   // 行已被选中
 * }
 */
function isSelected(row: Record<string, any>) {
  return arrays.objectInArray(row, selectedRows.value, props.rowKey);
}

/**
 * 切换指定行的选中状态
 * 可以强制设置行的选中状态或切换当前状态
 *
 * @param {Record<string, any>} row - 要切换选中状态的行数据对象
 * @param {boolean} [selected] - 可选，强制设置的选中状态
 *
 * @example
 * // 切换行的选中状态
 * toggleRowSelection(row);
 * 
 * // 强制设置行为选中状态
 * toggleRowSelection(row, true);
 */
function toggleRowSelection(row: Record<string, any>, selected?: boolean) {
  selectedRows.value = toggleRowSelectionHelper(row, selectedRows.value, props.rowKey, selected);
  emit('selection-change', selectedRows.value);
}

/**
 * 切换所有行的选中状态
 * 如果当前已全部选中则取消全选，否则选中所有行
 *
 * @example
 * // 点击全选复选框时调用
 * toggleAllSelection();
 */
function toggleAllSelection() {
  if (isAllSelected.value) {
    selectedRows.value = [];
  } else {
    selectedRows.value = [...data.value];
  }
  emit('selection-change', selectedRows.value);
}

/**
 * 清除所有行的选中状态
 * 清空已选行集合
 *
 * @example
 * // 清除所有选中行
 * clearSelection();
 */
function clearSelection() {
  selectedRows.value = [];
  emit('selection-change', selectedRows.value);
}

/**
 * 获取所有选中的行
 * 返回当前已选中的行数据集合
 *
 * @returns {Record<string, any>[]} - 已选中的行数据数组
 *
 * @example
 * const selected = getSelectionRows();
 * console.log('选中的行数量:', selected.length);
 */
function getSelectionRows() {
  return selectedRows.value;
}

/**
 * 设置当前行
 * 更新当前激活的行，并触发current-change事件
 *
 * @param {Record<string, any> | null} row - 要设置为当前行的数据对象或null
 *
 * @example
 * // 设置特定行为当前行
 * setCurrentRow(rowData);
 * 
 * // 清除当前行
 * setCurrentRow(null);
 */
function setCurrentRow(row: Record<string, any> | null) {
  oldCurrentRow.value = currentRow.value;
  currentRow.value = row;

  // 同时设置当前行索引
  if (row === null) {
    currentRowIndex.value = null;
  } else {
    currentRowIndex.value = data.value.indexOf(row);
  }

  emit('current-change', currentRow.value, oldCurrentRow.value);
}

// 监听数据变化
watch(() => props.data, (newData) => {
  if (newData) {
    internalData.value = newData;

    // 数据变化后，重新计算当前行索引
    if (currentRow.value !== null) {
      currentRowIndex.value = data.value.indexOf(currentRow.value);
    }
  }
}, { deep: true });

// 监听高度变化，检查是否需要固定表头
watch([() => props.height, () => props.maxHeight], () => {
  checkFixedHeader();
});

// 监听currentRowKey变化
watch(() => props.currentRowKey, (currentRowKey) => {
  if (currentRowKey !== undefined) {
    const row = data.value.find(r => {
      if (typeof props.rowKey === 'function') {
        return props.rowKey(r) === currentRowKey;
      } else if (typeof props.rowKey === 'string') {
        return objects.getProp(r, props.rowKey) === currentRowKey;
      }
      return false;
    });
    setCurrentRow(row || null);
  }
});

/**
 * 注册表格列
 * 将新的列定义添加到表格列集合中
 *
 * @param {TableColumnProps} column - 要注册的列定义对象
 *
 * @example
 * // 动态添加新列到表格
 * registerColumn({
 *   prop: 'newColumn',
 *   label: '新列'
 * });
 */
function registerColumn(column: TableColumnProps) {
  columns.value.push(column);
  checkFixedHeader();
}

/**
 * 注销表格列
 * 从表格列集合中移除指定的列定义
 *
 * @param {TableColumnProps} column - 要注销的列定义对象
 *
 * @example
 * // 动态从表格中移除列
 * unregisterColumn(columnToRemove);
 */
function unregisterColumn(column: TableColumnProps) {
  const index = columns.value.indexOf(column);
  if (index > -1) {
    columns.value.splice(index, 1);
  }
  checkFixedHeader();
}

// 创建响应式的表格上下文对象
const tableContext = ref<TableContext>({
  get columns() { return columns.value; },
  get data() { return data.value; },
  get sortState() { return sortState.value; },
  toggleRowSelection,
  clearSelection,
  getSelectionRows,
  registerColumn,
  unregisterColumn
});

// 提供表格上下文
provide('tableContext', tableContext);

// 暴露方法给父组件
defineExpose({
  toggleRowSelection,
  clearSelection,
  getSelectionRows,
  setCurrentRow
});
</script>

<style lang="scss" scoped>
.tui-table-wrapper {
  position: relative;
  overflow: hidden;

  &--has-fixed-header {
    /* 使用自定义滚动条组件，不需要overflow: auto */
    .tui-table__header {
      position: sticky;
      top: 0;
      z-index: 10;
      background-color: var(--tui-bg-color-light);
    }
  }
}

.tui-table {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
  text-align: left;
  empty-cells: show;

  &--border {
    border: 1px solid var(--tui-border-color-light);
  }

  &--stripe {
    tbody tr:nth-child(odd) {
      background-color: var(--tui-color-primary-light-9);
    }
  }

  &--small {
    font-size: var(--tui-font-size-small);
  }

  &--mini {
    font-size: var(--tui-font-size-extra-small);
  }

  &--medium {
    font-size: var(--tui-font-size-medium);
  }

  &__header {
    background-color: var(--tui-bg-color-light);

    .tui-table__cell--left,
    .tui-table__cell--right {
      background-color: var(--tui-bg-color-light);
    }
  }

  &__header-cell {
    padding: 12px 10px;
    border-bottom: 1px solid var(--tui-border-color-light);
    font-weight: 500;
    color: var(--tui-text-color-regular);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  &__body {
    background-color: var(--tui-color-white);
  }

  &__row {
    transition: all 0.3s;
  }

  /* 增加选择器特异性，确保hover效果能覆盖斑马纹 */
  tbody tr.tui-table__row:hover {
    background-color: var(--tui-color-primary-light-7);
  }

  &__row--current {
    background-color: var(--tui-color-primary-light-5);
  }

  /* 状态行样式 */
  .tui-table-row-success {
    background-color: var(--tui-color-success-light-9);
  }

  .tui-table-row-info {
    background-color: var(--tui-color-info-light-9);
  }

  .tui-table-row-warning {
    background-color: var(--tui-color-warning-light-9);
  }

  .tui-table-row-danger {
    background-color: var(--tui-color-danger-light-9);
  }

  &__cell {
    padding: 12px 10px;
    border-bottom: 1px solid var(--tui-border-color-light);
    color: var(--tui-text-color-secondary);
    font-size: var(--tui-font-size-base);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;

    &--left,
    &--right {
      position: sticky;
      background-color: var(--tui-bg-color);
      z-index: 1;
    }

    &--left {
      left: 0;
    }

    &--right {
      right: 0;
    }

    &--overflow-tooltip {
      position: relative;
      cursor: help;
    }
  }

  &__cell-wrapper {
    display: flex;
    align-items: center;
  }

  &__column-label {
    flex: 1;
  }

  &__sortable {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    margin-left: 4px;
    cursor: pointer;

    .tui-icon {
      font-size: var(--tui-font-size-small);
      color: var(--tui-text-color-placeholder);
      transition: color 0.3s;
      width: 14px;
      height: 14px;

      &.is-active {
        color: var(--tui-color-primary);
      }
    }
  }

  &__empty-row {
    height: 100px;
  }

  &__empty-cell {
    text-align: center;
    padding: 40px 10px;
  }

  &__empty-text {
    color: var(--tui-text-color-placeholder);
  }

  &__overflow-tooltip-wrapper {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  &__index {
    color: var(--tui-text-color-secondary);
  }
}

// 复选框样式
.tui-checkbox {
  &__original {
    position: absolute;
    opacity: 0;
    margin: 0;
    padding: 0;

    &:checked {
      +.tui-checkbox__inner {
        background-color: var(--tui-color-primary);
        border-color: var(--tui-color-primary);

        &::after {
          content: '';
          position: absolute;
          left: 4px;
          top: 2px;
          width: 4px;
          height: 8px;
          border: 2px solid var(--tui-bg-color);
          border-top: none;
          border-left: none;
          transform: rotate(45deg);
        }
      }
    }
  }

  &__inner {
    position: relative;
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 1px solid var(--tui-border-color);
    border-radius: var(--tui-border-radius-small);
    background-color: var(--tui-bg-color);
    transition: all 0.3s;
  }
}
</style>